package com.example.demo3stream;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

/**
 * 目标：掌握Stream提供的常用的中间方法，对流上的数据进行处理（返回新流：支持链式编程）
 */
public class StreamDemo3 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");
        list.add("张翠山");

        // 1、过滤方法
        list.stream().filter(s -> s.startsWith("张") && s.length() == 3).forEach(System.out::println);

        // 2、排序方法。
        List<Double> scores = new ArrayList<>();
        scores.add(88.6);
        scores.add(66.6);
        scores.add(66.6);
        scores.add(77.6);
        scores.add(77.6);
        scores.add(99.6);

        // 排序
        scores.stream().sorted().forEach(System.out::println); // 默认是按照升序排的
        System.out.println("--------------------------------------------------------------------------");
        // 降序 只需要给sort方法传递一个比较器即可
        /*scores.stream().sorted(new Comparator<Double>() {
            @Override
            public int compare(Double o1, Double o2) {
                return Double.compare(o2, o1);
            }
        }).forEach(System.out::println);*/

        // 以上的代码可以使用Lambda简化
        scores.stream().sorted((o1, o2) -> Double.compare(o2, o1)).forEach(System.out::println);

        System.out.println("--------------------------------------------------------------------------");
        // limit获取前几个元素
        // 需求值要获取前2个元素
        scores.stream().sorted((o1, o2) -> Double.compare(o2, o1)).limit(2).forEach(System.out::println); // 获取前2个元素

        System.out.println("--------------------------------------------------------------------------");

        // skip跳过前几个元素
        scores.stream().sorted((o1, o2) -> Double.compare(o2, o1)).skip(2).forEach(System.out::println); // 跳过前2个元素

        // 3.去重方法 distinct
        scores.stream().sorted((o1, o2) -> Double.compare(o2, o1)).distinct().forEach(System.out::println); // 去重

        // 如果需要实现自定义对象的去重，需要重写对象的hashCode和equals方法

        System.out.println("--------------------------------------------------------------------------");
        // map映射方法 把流上原来的数据拿出来变成新数据又放到流上去。
        // 需求：给集合中的元素增加10分
        scores.stream().map(s -> s + 10).forEach(System.out::println);

        // 合并流：
        Stream<String> s1 = Stream.of("张三丰", "张无忌", "张翠山", "张良", "张学友");
        Stream<Integer> s2 = Stream.of(111, 22, 33, 44);
        // 为什么和并之后的流泛型是Object 因为不能确定流合中元素的类型
        Stream<Object> s3 = Stream.concat(s1, s2);
        System.out.println(s3.count());
    }
}
